
package com.be.beadmin.project.impl;


import com.be.beadmin.basicData.dto.output.LabelValue;
import com.be.beadmin.basicData.entity.Role;
import com.be.beadmin.basicData.entity.User;
import com.be.beadmin.basicData.repository.RoleRepository;
import com.be.beadmin.basicData.repository.UserRepository;
import com.be.beadmin.basicData.service.RoleService;
import com.be.beadmin.basicData.service.UserService;
import com.be.beadmin.common.entity.PageEntity;
import com.be.beadmin.common.exception.BeadminException;
import com.be.beadmin.common.utils.JpaQueryBuilder;
import com.be.beadmin.common.utils.JpaSortBuilder;
import com.be.beadmin.project.dto.input.TeamInfoByTypeDto;
import com.be.beadmin.project.dto.input.TeamInfoDto;
import com.be.beadmin.project.dto.input.TeamInfoPageDto;
import com.be.beadmin.project.dto.output.TeamInfoByTypeEx;
import com.be.beadmin.project.dto.output.TeamInfoEx;
import com.be.beadmin.project.dto.output.UserInfoSimpEx;
import com.be.beadmin.project.entity.Info;
import com.be.beadmin.project.entity.Team;
import com.be.beadmin.project.entity.TeamInfo;
import com.be.beadmin.project.entity.TeamInfo_;
import com.be.beadmin.project.mapper.TeamInfoMapper;
import com.be.beadmin.project.mapper.TeamInfoMapperEx;
import com.be.beadmin.project.repository.TeamInfoRepository;
import com.be.beadmin.project.repository.TeamRepository;
import com.be.beadmin.project.service.InfoService;
import com.be.beadmin.project.service.TeamInfoService;
import com.be.beadmin.project.service.TeamService;
import com.be.beadmin.service.dto.output.DictDataEx;
import com.be.beadmin.service.entity.DictType;
import com.be.beadmin.service.repository.DictTypeRepository;
import com.be.beadmin.service.service.DictDataService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Order;
import javax.persistence.criteria.Predicate;
import java.util.*;

/**
* @description 服务实现
* @author zjm
* @date 2023-02-02
**/
@Service
@RequiredArgsConstructor
public class TeamInfoServiceImpl implements TeamInfoService {

    @Autowired
    private  TeamInfoRepository teamInfoRepository;
    @Autowired
    private TeamInfoServiceImpl teamInfoService;
    @Autowired
    private TeamRepository teamRepository;
    @Autowired
    private InfoService infoService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private RoleRepository roleRepository;
    @Autowired
    private  TeamInfoMapper teamInfoMapper;
    @Autowired
    private  TeamInfoMapperEx teamInfoExMapper;
    @Autowired
    private DictTypeRepository dictTypeRepository;
    @Autowired
    private DictDataService dictDataService;
    @Autowired
    private TeamService teamService;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private UserService userService;
    @Override
    public Page<TeamInfoEx> getTeamInfoByPage(PageEntity pageEntity) {
            Pageable pageable = PageRequest.of(
            pageEntity.getCurrent() -1,
            pageEntity.getPageSize());
            Page<TeamInfo> page = teamInfoRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 =   JpaQueryBuilder.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate pre2 = criteriaBuilder.equal(root.get(TeamInfo_.delete), 0); //过滤为0
                    list.add(pre2);
                    Predicate[] p = new Predicate[list.size()];

                    List<Order> orders = new ArrayList<>();
                    if(pageEntity.getSorters() != null && pageEntity.getSorters().size() > 0) {
                        orders = JpaSortBuilder.getPredicate(root, pageEntity.getSorters(), criteriaBuilder);
                        criteriaQuery.orderBy(orders);
                    } else {
                        criteriaQuery.orderBy(criteriaBuilder.desc(root.get(TeamInfo_.createTime).as(Date.class)));
                    }
                    System.out.println("criteriaQuery"+criteriaQuery);
                    return  criteriaBuilder.and(list.toArray(p));
                    }
                    , pageable);

            Page<TeamInfoEx> page1 = page.map(teamInfoExMapper::toEntity);
//            Page<TeamInfoEx> page1 = page.map(teamInfoService::addTeamProper);
//            page1 = page.map(page1->);
            return page1;

    }
//    public TeamInfoEx addTeamProper(TeamInfo dto){
//        if ( dto == null ) {
//            return null;
//        }
//
//        TeamInfoEx teamInfoEx = new TeamInfoEx();
//        if ( dto.getId() != null ) {
//            teamInfoEx.setId( dto.getId() );
//        }
//        if ( dto.getCreateTime() != null ) {
//            teamInfoEx.setCreateTime( dto.getCreateTime() );
//        }
//        if ( dto.getCreateName() != null ) {
//            teamInfoEx.setCreateName( dto.getCreateName() );
//        }
//        if ( dto.getCategory() != null ) {
//            teamInfoEx.setCategory( dto.getCategory() );
//        }
//        if ( dto.getMemo() != null ) {
//            teamInfoEx.setMemo( dto.getMemo() );
//        }
//        if ( dto.getReserved() != null ) {
//            teamInfoEx.setReserved( dto.getReserved() );
//        }
//        if ( dto.getRoleId() != null ) {
//            teamInfoEx.setRoleId( dto.getRoleId() );
//        }
//        if ( dto.getRoleName() != null ) {
//            teamInfoEx.setRoleName( dto.getRoleName() );
//        }
//        if ( dto.getSerialNo() != null ) {
//            teamInfoEx.setSerialNo( dto.getSerialNo() );
//        }
//        if ( dto.getUserId() != null ) {
//            teamInfoEx.setUserId( dto.getUserId() );
//        }
//        if ( dto.getUserName() != null ) {
//            teamInfoEx.setUserName( dto.getUserName() );
//        }
//        if ( dto.getTeam() != null ) {
//            teamInfoEx.setTeamId( dto.getTeam().getId());
//        }
//        return teamInfoEx;
//
//    }
    @Override
    public int addTeamInfo(TeamInfoDto teamInfoDto) {
//            TeamInfo result = teamInfoRepository.findTeamInfoByIdAndDelete(teamInfoDto.getId(), 0);
            List<TeamInfo> result = teamInfoRepository.findTeamInfoByTeamIdAndUserIdAndCategoryAndDelete(teamInfoDto.getTeamId(),teamInfoDto.getUserId(),teamInfoDto.getCategory(), 0);
            List<String> roleType = teamService.getRoleType();
            if (!roleType.contains(teamInfoDto.getCategory())){
                return -2;
            }
            if(result.size()!=0) {
                return -1;
            }
        //            if(ObjectUtil.isNotEmpty(result)) {
//                throw new BeadminException("TeamInfo不存在,请重新查询");
//            }
        //各个经理只有一个
            String category = teamInfoDto.getCategory();
            if(category.contains("经理")){
                List<TeamInfo> managerList = teamInfoRepository.findTeamInfosByTeamIdAndCategoryAndDelete(teamInfoDto.getTeamId(),teamInfoDto.getCategory(),0);
                if(managerList.size()>=1) return -3;
            }

            TeamInfo teamInfo = teamInfoMapper.toEntity(teamInfoDto);

//            Team team = teamRepository.findTeamById(teamInfoDto.getTeamId());
//            teamInfo.setTeam(team);
//            System.out.println("teamInfo:"+teamInfo);
            teamInfoRepository.save(teamInfo);


            return 1;
    }
    @Override
    public void addTeamInfos(List<TeamInfoDto> teamInfoDtos, Team team) {

//        TeamInfo result = teamInfoRepository.findTeamInfoByIdAndDelete(teamInfoDto.getId(), 0);
//        if(ObjectUtil.isNotEmpty(result)) {
//            throw new BeadminException("TeamInfo不存在,请重新查询");
//        }


        List<TeamInfo> teamInfos = teamInfoMapper.toEntity(teamInfoDtos);
//        teamInfos.forEach(teamInfo -> teamInfo.setTeam(team));
        teamInfoRepository.saveAll(teamInfos);
    }

    /**
     * 获取指定id的团队成员信息
     *
     * @param teamInfoId
     * @return
     */
    @Override
    public TeamInfo getTeamByIdAndDelete(String teamInfoId) {
        return teamInfoRepository.findTeamInfoByIdAndDelete(teamInfoId,0);
    }

    /**
     * 获取所有角色类型
     *
     * @return
     */
    @Override
    public List<String> getRoleType() {
        // 角色类型字典内容
////        DictTypeEx dictTypeEx = dictTypeService.getDictTypeByName("项目团队角色类型");
//        DictType dictType = dictTypeRepository.findDictTypeByDictName("项目团队角色类型");
////        System.out.println("dictTypeEx:"+dictTypeEx);
////        String roleTypeCode = dictTypeEx.getDictCode();
////        System.out.println("roleTypeCode:"+roleTypeCode);
//        List<DictDataEx> roleType =  dictDataService.getDictDataExByDictTypeId(dictType);
        List<String> roleTypeList = new ArrayList<>();
//        roleType.forEach(role-> roleTypeList.add(role.getKeyName()));

        // 得用角色管理中的角色了。
        for (LabelValue labelValue : roleService.getRoleList()) {
            roleTypeList.add(labelValue.getLabel());
        }
       Collections.sort(roleTypeList);
        return roleTypeList;
    }

    /**
     * 获取所有用户的简易信息
     *
     * @return
     */
    @Override
    public List<UserInfoSimpEx> getUserInfoSimp() {
        List<User> userList = userRepository.findAll();
        List<UserInfoSimpEx> userInfoSimpDtos = new ArrayList<>();
        for (int i = 0; i < userList.size(); i++) {
            UserInfoSimpEx userInfoSimpDto = new UserInfoSimpEx();
            userInfoSimpDto.setUserId(userList.get(i).getId());
            userInfoSimpDto.setUserName(userList.get(i).getName());
//            projectInfoSimp.setInfoId(infoList.get(i).getProjectCode());
            if (userList.get(i).getDelete()==0){
                userInfoSimpDtos.add(userInfoSimpDto);
            }

        }
        return userInfoSimpDtos;
    }

    @Override
    public List<TeamInfo> getTeamInfoByInfoId(String infoId) {
        Info infoIdById = infoService.getInfoIdById(infoId);
        Team team = teamService.getTeamByIdAndDelete(infoIdById.getTeamId());
        List<TeamInfo> teamInfos = teamInfoRepository.findTeamInfoByTeamIdAndDelete(team.getId(), 0);
        return teamInfos;
    }

    /**
     * 获取指定项目的某个角色类型的成员
     *
     * @param infoId
     * @param category
     * @return
     */
    @Override
    public List<TeamInfo> getTeamInfoByInfoIdAndType(String infoId, String category) {

        Info infoIdById = infoService.getInfoIdById(infoId);
        Team team = teamService.getTeamByIdAndDelete(infoIdById.getTeamId());
        List<TeamInfo> teamInfoList = teamInfoRepository.findTeamInfosByTeamIdAndCategoryAndDelete(team.getId(),category, 0);
        return teamInfoList;
    }

    /**
     * 获取指定项目的某个角色类型的成员姓名
     *
     * @param infoId
     * @param category
     * @return
     */
    @Override
    public List<String> getNameByInfoIdAndType(String infoId, String category) {

        Info infoIdById = infoService.getInfoIdById(infoId);
        Team team = teamService.getTeamByIdAndDelete(infoIdById.getTeamId());
        List<String> names = teamInfoRepository.findNameByTeamIdAndCategoryAndDelete(team.getId(),category, 0);
        return names;
    }

    /**
     * 为一种角色添加多个团队成员
     */
    @Override
    public void addTeamInfoByRoleType(TeamInfoByTypeDto teamInfoByTypeDto) {
        String teamId = teamInfoByTypeDto.getTeamId();
        Team teamByIdAndDelete = teamService.getTeamByIdAndDelete(teamId);
        if (teamByIdAndDelete == null) {
            throw new BeadminException("未找到该团队");
        }
        String roleType = teamInfoByTypeDto.getRoleType();
        Role role = roleRepository.findRoleByNameAndDelete(roleType, 0);
        if (role == null) {
            throw new BeadminException("没有找到这个角色:"+roleType);
        }

        for (String userId : teamInfoByTypeDto.getUserIds()) {
            if (userId.equals("")) continue;
            User userById = userService.getUserById(userId);

            if (userById == null) {
                continue;
            }
            if (!userService.isRole(userById,roleType)) {
                throw new BeadminException("该用户:"+userById.getName()+"不是:" + roleType);
            }
            List<TeamInfo> infoList = teamInfoRepository.findTeamInfoByTeamIdAndRoleNameAndUserIdAndDelete(teamId, roleType, userId, 0);
            if (!infoList.isEmpty()) continue;

            TeamInfo teamInfo = new TeamInfo();
            teamInfo.setTeamId(teamId);
            teamInfo.setCategory(roleType);
            teamInfo.setRoleName(role.getName());
            teamInfo.setRoleId(role.getId());
            teamInfo.setEmail(userById.getEmail());
            teamInfo.setUserId(userById.getId());
            teamInfo.setUserName(userById.getName());
            teamInfo.setPhone(userById.getPhone());
            teamInfoRepository.save(teamInfo);
        }
        teamService.updateTeamState(teamId);
    }

    /**
     * 分页获得团队所有团队成员--按照角色分
     *
     * @param teamInfoPageDto
     * @return
     */
    @Override
    public String getTeamInfosByPageAndRoleType(TeamInfoPageDto teamInfoPageDto) {
        // 某一个角色下的所有


        return null;
    }

    /**
     * 获得团队所有团队成员--按照角色分
     *
     * @param teamId
     * @return
     */
    @Override
    public List<TeamInfoByTypeEx> getAllTeamInfosByRoleType(String teamId) {
        List<TeamInfoByTypeEx> list = new ArrayList<>();
        for (LabelValue labelValue : roleService.getRoleList()) {
            List<TeamInfo> teamInfoList = teamInfoRepository.findTeamInfoByTeamIdAndRoleNameAndDelete(teamId, labelValue.getLabel(), 0);
            if (!teamInfoList.isEmpty()) {
                TeamInfoByTypeEx teamInfoByTypeEx = new TeamInfoByTypeEx();
                teamInfoByTypeEx.setRoleType(labelValue.getLabel());
                teamInfoByTypeEx.setTeamId(teamId);
                teamInfoByTypeEx.setTeamInfoEx(teamInfoExMapper.toEntity(teamInfoList));
                list.add(teamInfoByTypeEx);
            }


        }
        return list;
    }

    /**
     * 获得团队某个角色的所有团队成员
     * @param teamId
     * @param roleType
     * @return
     */
    @Override
    public List<TeamInfo> getTeamInfosByRoleType(String teamId, String roleType) {
        return teamInfoRepository.findTeamInfoByTeamIdAndRoleNameAndDelete(teamId, roleType, 0);

    }

    /**
     * 为一种角色修改团队成员
     *
     * @param teamInfoByTypeDto
     */
    @Override
    public void updateTeamInfosByRoleType(TeamInfoByTypeDto teamInfoByTypeDto) {
        // 先删除掉这些记录
        delTeamInfosByRoleType(teamInfoByTypeDto.getTeamId(),teamInfoByTypeDto.getRoleType());
        // 再添加上
        addTeamInfoByRoleType(teamInfoByTypeDto);
    }

    /**
     * 删除某一种角色团队成员
     * @param teamId
     * @param roleType
     */
    @Override
    public void delTeamInfosByRoleType(String teamId, String roleType) {
        teamInfoRepository.deleteTeamInfosByTeamIdAndRoleName(teamId,roleType);
    }

    /**
     * 删除某一个团队成员
     * @param teamId
     * @param userId
     */
    @Override
    public void delOneTeamMember(String teamId, String userId, String roleId) {
        teamInfoRepository.deleteTeamInfoByTeamIdAndUserIdAndRoleId(teamId,userId,roleId);
    }

    /**
     * 批量删除某些角色团队成员
     * @param teamId
     * @param roleTypes
     */
    @Override
    public void delBatchTeamInfosByRoleType( String teamId,  List<String> roleTypes) {
        for (String roleType : roleTypes) {
            delTeamInfosByRoleType(teamId,roleType);
        }
    }


    @Override
    public int updateTeamInfo(TeamInfoDto teamInfoDto) {
//        List<TeamInfo> result = teamInfoRepository.findTeamInfoByTeamIdAndUserIdAndCategoryAndDelete(teamInfoDto.getTeamId(),teamInfoDto.getUserId(),teamInfoDto.getCategory(), 0);
        List<String> roleType = teamService.getRoleType();
        if (!roleType.contains(teamInfoDto.getCategory())){
            return -2;
        }
        TeamInfo result = teamInfoRepository.findTeamInfoByIdAndDelete(teamInfoDto.getId(),0);

//        if(!Objects.equals(result.getTeamId(), teamInfoDto.getTeamId()) || !Objects.equals(result.getUserId(), teamInfoDto.getUserId()) ) {
//            return -1;
//        }
//        TeamInfo teamInfo = teamInfoRepository.findTeamInfoById(teamInfoDto.getId());



        TeamInfo teamInfo = teamInfoMapper.toEntity(teamInfoDto);
        teamInfoRepository.save(teamInfo);
        return 1;
    }


    @Override
    public void delTeamInfo(String id) {
        TeamInfo teamInfo = teamInfoRepository.findTeamInfoById(id);
        teamInfo.setDelete(1);
        teamInfoRepository.save(teamInfo);
    }

    @Override
    public void delTeamInfos (List<String> ids) { }
}